<template>
  <el-select
      v-model="selectValue"
      v-bind="attr"
      remote
      reserve-keyword
      v-lazy="test"
      :remote-method="remoteMethod"
      :loading="loading">
    <el-option
        v-for="item in options"
        :key="valueKey ? item[valueKey] : item"
        :label="labelKey ? item[labelKey] : item"
        :value="valueKey ? item[valueKey] : item">
    </el-option>
  </el-select>
</template>

<script>
// TODO if value default has data, need to be handle
export default {
  name: 'select-lazy',
  props: {
    value: {
      type: [String, Array]
    },
    labelKey: {
      required: true,
      type: String
    },
    valueKey: {
      required: true,
      type: String
    },
    allData: {
      required: true,
      type: Array
    },
    attr: {}
  },
  data () {
    return {
      loading: false,
      currentList: [],
      list: [],
      options: [],
      totalPage: 1,
      currentPage: 1,
      pageSize: 10
    }
  },
  computed: {
    selectValue: {
      get () {
        return this.value
      },
      set (val) {
        this.$emit('input', val)
      }
    }
  },
  watch: {
    allData: {
      handler () {
        this.init()
      },
      deep: true,
      immediate: true
    }
  },
  directives: {
    lazy: {
      bind (el, binding) {
        const SELECTWRAP_DOM = el.querySelector(
          '.el-select-dropdown .el-select-dropdown__wrap'
        )
        SELECTWRAP_DOM.addEventListener('scroll', function () {
          const condition = this.scrollHeight - this.scrollTop <= this.clientHeight
          if (condition) {
            binding.value()
          }
        })
      }
    }
  },
  methods: {
    test () {
      if (this.totalPage > this.currentPage) {
        this.currentPage++
        const data = this.currentList.slice((this.currentPage - 1) * this.pageSize, this.currentPage * this.pageSize)
        this.options = this.options.concat(data)
      }
    },
    remoteMethod (query) {
      if (query !== '') {
        this.loading = true
        setTimeout(() => {
          this.loading = false
          this.currentList = this.allData.filter(item => {
            return (this.labelKey ? item[this.labelKey] : item).toLowerCase()
              .indexOf(query.toLowerCase()) > -1
          })
          this.init(this.currentList)
        }, 200)
      } else {
        this.init()
      }
    },
    init (data) {
      this.currentPage = 1
      this.currentList = data || this.allData
      this.totalPage = Math.ceil(this.currentList.length / this.pageSize)
      this.options = this.currentList.slice(0, this.pageSize)
    }
  }
}
</script>

<style scoped>

</style>
